/*
 * Copyright (C) 2008,2009  OMRON SOFTWARE Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.googlecode.openwnn.legacy;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;

import org.xmlpull.v1.XmlPullParserException;

import android.content.SharedPreferences;
import android.content.res.XmlResourceParser;
import android.util.Log;

import com.example.softwaretest.R;

/**
 * The generator class of symbol list. <br>
 * This class is used for generating lists of symbols.
 * 
 * @author Copyright (C) 2009 OMRON SOFTWARE CO., LTD. All Rights Reserved.
 */
public class SymbolList implements WnnEngine {
	/*
	 * DEFINITION OF CONSTANTS
	 */
	/** Language definition (English) */
	public static final int LANG_EN = 0;

	/** Language definition (Japanese) */
	public static final int LANG_JA = 1;

	/** Language definition (Chinese) */
	public static final int LANG_ZHCN = 2;

	/** Key string to get normal symbol list for Japanese */
	public static final String SYMBOL_JAPANESE = "j";

	/** Key string to get normal symbol list for English */
	public static final String SYMBOL_ENGLISH = "e";

	/** Key string to get normal symbol list for Chinese */
	public static final String SYMBOL_CHINESE = "c";

	/** Key string to get emotion list */
	public static final String SYMBOL_EMOTION = "emotion";

	/** The name of XML tag key */
	private static final String XMLTAG_KEY = "string";

	/*
	 * DEFINITION OF VARIABLES
	 */
	/** Symbols data */
	protected HashMap<String, ArrayList<String>> mSymbols;

	/** OpenWnn which has this instance */
	private OpenWnn mWnn;

	/** current list of symbols */
	private ArrayList<String> mCurrentList;

	/** Iterator for getting symbols from the list */
	private Iterator<String> mCurrentListIterator;

	/*
	 * DEFINITION OF METHODS
	 */
	/**
	 * Constructor
	 * 
	 * @param parent
	 *            OpenWnn instance which uses this.
	 * @param lang
	 *            Language ({@code LANG_EN}, {@code LANG_JA} or
	 *            {@code LANG_ZHCN})
	 */
	public SymbolList(OpenWnn parent, int lang) {
		mWnn = parent;
		mSymbols = new HashMap<String, ArrayList<String>>();

		switch (lang) {
		case LANG_EN:
			/* symbols for English IME */
			mSymbols.put(SYMBOL_ENGLISH, getXmlfile(R.xml.symbols_latin12_list));
			mSymbols.put(SYMBOL_EMOTION, getXmlfile(R.xml.symbols_emotion_list));
			mCurrentList = mSymbols.get(SYMBOL_ENGLISH);
			break;

		case LANG_JA:
			/* symbols for Japanese IME */
			mSymbols.put(SYMBOL_JAPANESE, getXmlfile(R.xml.symbols_japan_list));
			mSymbols.put(SYMBOL_ENGLISH, getXmlfile(R.xml.symbols_latin1_list));
			mSymbols.put(SYMBOL_EMOTION, getXmlfile(R.xml.symbols_emotion_list));
			mCurrentList = mSymbols.get(SYMBOL_JAPANESE);
			break;

		case LANG_ZHCN:
			/* symbols for Chinese IME */
			mSymbols.put(SYMBOL_CHINESE, getXmlfile(R.xml.symbols_china_list));
			mSymbols.put(SYMBOL_ENGLISH, getXmlfile(R.xml.symbols_latin1_list));
			mSymbols.put(SYMBOL_EMOTION, getXmlfile(R.xml.symbols_emotion_list));
			mCurrentList = mSymbols.get(SYMBOL_CHINESE);
			break;
		}

		mCurrentList = null;
	}

	/**
	 * Get a attribute value from a XML resource.
	 * 
	 * @param xrp
	 *            XML resource
	 * @param name
	 *            The attribute name
	 * 
	 * @return The value of the attribute
	 */
	private String getXmlAttribute(XmlResourceParser xrp, String name) {
		int resId = xrp.getAttributeResourceValue(null, name, 0);
		if (resId == 0) {
			return xrp.getAttributeValue(null, name);
		} else {
			return mWnn.getString(resId);
		}
	}

	/**
	 * Load a symbols list from XML resource.
	 * 
	 * @param id
	 *            XML resource ID
	 * @return The symbols list
	 */
	private ArrayList<String> getXmlfile(int id) {
		ArrayList<String> list = new ArrayList<String>();

		XmlResourceParser xrp = mWnn.getResources().getXml(id);
		try {
			int xmlEventType;
			while ((xmlEventType = xrp.next()) != XmlResourceParser.END_DOCUMENT) {
				if (xmlEventType == XmlResourceParser.START_TAG) {
					String attribute = xrp.getName();
					if (XMLTAG_KEY.equals(attribute)) {
						String value = getXmlAttribute(xrp, "value");
						if (value != null) {
							list.add(value);
						}
					}
				}
			}
			xrp.close();
		} catch (XmlPullParserException e) {
			Log.e("OpenWnn", "Ill-formatted keybaord resource file");
		} catch (IOException e) {
			Log.e("OpenWnn", "Unable to read keyboard resource file");
		}

		return list;
	}

	/**
	 * Set the dictionary
	 * 
	 * @param listType
	 *            The list of symbol
	 * @return {@code true} if valid type is specified; {@code false} if not;
	 */
	public boolean setDictionary(String listType) {
		mCurrentList = mSymbols.get(listType);
		return (mCurrentList != null);
	}

	/***********************************************************************
	 * WnnEngine's interface
	 **********************************************************************/
	/** @see com.googlecode.openwnn.legacy.WnnEngine#init */
	public void init() {
	}

	/** @see com.googlecode.openwnn.legacy.WnnEngine#close */
	public void close() {
	}

	/** @see com.googlecode.openwnn.legacy.WnnEngine#predict */
	public int predict(ComposingText text, int minLen, int maxLen) {
		/* ignore if there is no list for the type */
		if (mCurrentList == null) {
			mCurrentListIterator = null;
			return 0;
		}

		/* return the iterator of the list */
		mCurrentListIterator = mCurrentList.iterator();
		return 1;
	}

	/** @see com.googlecode.openwnn.legacy.WnnEngine#convert */
	public int convert(ComposingText text) {
		return 0;
	}

	/** @see com.googlecode.openwnn.legacy.WnnEngine#searchWords */
	public int searchWords(String key) {
		return 0;
	}

	/** @see com.googlecode.openwnn.legacy.WnnEngine#searchWords */
	public int searchWords(WnnWord word) {
		return 0;
	}

	/** @see com.googlecode.openwnn.legacy.WnnEngine#getNextCandidate */
	public WnnWord getNextCandidate() {
		if (mCurrentListIterator == null || !mCurrentListIterator.hasNext()) {
			return null;
		}
		String str = mCurrentListIterator.next();
		WnnWord word = new WnnWord(str, str);
		return word;
	}

	/** @see com.googlecode.openwnn.legacy.WnnEngine#learn */
	public boolean learn(WnnWord word) {
		return false;
	}

	/** @see com.googlecode.openwnn.legacy.WnnEngine#addWord */
	public int addWord(WnnWord word) {
		return 0;
	}

	/** @see com.googlecode.openwnn.legacy.WnnEngine#deleteWord */
	public boolean deleteWord(WnnWord word) {
		return false;
	}

	/** @see com.googlecode.openwnn.legacy.WnnEngine#setPreferences */
	public void setPreferences(SharedPreferences pref) {
	}

	/** @see com.googlecode.openwnn.legacy.WnnEngine#breakSequence */
	public void breakSequence() {
	}

	/** @see com.googlecode.openwnn.legacy.WnnEngine#makeCandidateListOf */
	public int makeCandidateListOf(int clausePosition) {
		return 0;
	}

	/** @see com.googlecode.openwnn.legacy.WnnEngine#initializeDictionary */
	public boolean initializeDictionary(int dictionary) {
		return true;
	}

	/** @see com.googlecode.openwnn.legacy.WnnEngine#initializeDictionary */
	public boolean initializeDictionary(int dictionary, int type) {
		return true;
	}

	/** @see com.googlecode.openwnn.legacy.WnnEngine#getUserDictionaryWords */
	public WnnWord[] getUserDictionaryWords() {
		return null;
	}
}
